#pragma once

#include <Plane.h>
#include <PlaneParas.hpp>
#include <CGAL_Utils.hpp>

typedef std::pair<int, int> Edge;
typedef std::vector<Edge> Edges;
typedef std::pair<pcl::PointXYZ, pcl::PointXYZ> Line;
typedef std::vector<std::pair<Line, LABEL_TYPE>> Framework;

class WallPlane
{
public:
    WallPlane(const Plane& p) :
        para(PlaneParas(p)),
        vertices(CGAL_Utils::getVertices(p)),
        ceiling_edge(std::make_pair(-1, -1)),
        floor_edge(std::make_pair(-1, -1))
    {
         
    }

    void setId(int value){ id = value; }
 
    void addLine(const Edge& edge, const LABEL_TYPE &label)
    {
        if(edge.first != -1 && edge.second != -1)
            framework.push_back(std::make_pair(getLine(edge), label));
    }

    // 从vertices和edges中获得最终的framework
    void updateFramework()
    {
        framework.clear();
        addLine(ceiling_edge, CEILING);
        addLine(floor_edge, FLOOR);
        for(auto w_e : wall_edges)
            addLine(w_e, WALL);
    }
    
    const Framework& getFramework() const { return framework;}

    void operator=(const WallPlane& w)
    {
        para = w.para;
        vertices = w.vertices;
        ceiling_edge = w.ceiling_edge;
        floor_edge = w.floor_edge;
        wall_edges = w.wall_edges;
        updateFramework();
    }

    PlaneParas para;
    Points vertices;
    Edge ceiling_edge, floor_edge; 
    Edges wall_edges;
    int id;

private:
    Framework framework;
    Line getLine(const Edge& edge) const { return std::make_pair(getPoint(edge.first), getPoint(edge.second)); }
    pcl::PointXYZ getPoint(int i) const { return pcl::PointXYZ(vertices[i].x(), vertices[i].y(), vertices[i].z()); }
};